#ifndef COMMUNICATIONS_TLSSOCKET_TLSTCP_H
#define COMMUNICATIONS_TLSSOCKET_TLSTCP_H

#ifdef __cplusplus
extern "C" {
#endif
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/debug.h>
#include <mbedtls/entropy.h>
#include <mbedtls/error.h>
#include <mbedtls/hmac_drbg.h>
#include <mbedtls/md5.h>
#include <mbedtls/net_sockets.h>
#include <mbedtls/platform.h>
#include <mbedtls/ssl.h>

#ifdef __cplusplus
}
#endif

#include "communication.h"
#include <string>
#include <utils/lock.h>

namespace communication {
class TlsTcp : public Communication {
public:
    TlsTcp();
    virtual ~TlsTcp();
    virtual bool IsConnected() const
    {
        return connect_;
    }

protected:
    virtual std::string name() const;
    virtual bool Connect(const std::string &host, int port);

    void DisConnect();
    int SendWithReply(const char *data, int len, char reply[]);
    int32_t SendData(const char *data, int len);
    int RecvData(char reply[], int max = -1, int timeout = 3000);

private:
    bool initTls();
    void destroyTls();
    static void TlsDebug(void *ctx, int level, const char *file, int line, const char *str);

private:
    mbedtls_net_context serverFd_ = {-1};
    mbedtls_entropy_context entropyContext_;
    mbedtls_ctr_drbg_context ctrDrbg_;
    mbedtls_ssl_config sslConf_;
    mbedtls_x509_crt cacert_;
    mbedtls_ssl_context sslContext_;
    Lock lockSsl_;

    std::string host_;
    int port_;
    bool init_ = false;
    bool connect_;
};
} // namespace communication
#endif // COMMUNICATIONS_TLSSOCKET_TLSTCP_H